package com.waitingresult.demo.aspect;

import cn.hutool.core.util.ObjUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.waitingresult.demo.annotation.Log;
import com.waitingresult.demo.annotation.LogName;
import com.waitingresult.demo.entity.LogEntity;
import com.waitingresult.demo.entity.OpLog;
import com.waitingresult.demo.enums.BaseEnum;
import com.waitingresult.demo.enums.MysqlModeEnums;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;

/**
 * @Author: WangShuai
 * @CreateTime: 2023/5/17  18:09
 * @Description:
 * @Version: 1.0
 */
@Slf4j
@Component
@Aspect
public class LogAspectj {

    @Resource
    private RedisTemplate redisTemplate;

    @Pointcut("@annotation(com.waitingresult.demo.annotation.Log)")
    public void pointcut() {
    }

    // 1. 取 老值 和新值 做比对, 生成字符串, 存入数据库
    @Around("pointcut()")
    public void afterSaveLog(ProceedingJoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        Object[] args = joinPoint.getArgs();
        String jsonString = "";
        String id = "";
        String recordString = "";
        JSONObject jsonObject = new JSONObject();
        for (Object arg : args) {
            String s = JSON.toJSONString(arg);
            jsonString = s;
            jsonObject = JSONObject.parseObject(s);
            id = String.valueOf(jsonObject.get("id"));
            if (arg instanceof List) {
                log.info("集合处理");
            }
            if (arg instanceof Integer) {
                log.info("数字处理");
            }
            log.info("args:{}", arg);
        }

        // 获取 日志记录注解
        Log opLog = method.getAnnotation(Log.class);
        // 操作DO类
        Class clazz = opLog.clazz();
        String redisKey = opLog.redisKey() + id;
        Object redisResponse = redisTemplate.opsForValue().get(redisKey);
        JSONObject redisOldJson = JSONObject.parseObject(String.valueOf(redisResponse));
        //DO类的所有字段
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            LogName annotation = field.getAnnotation(LogName.class);
            //查找需要记录的 字段信息
            if (ObjUtil.isNotEmpty(annotation)) {
                String name = field.getName();
                Object requestCode = jsonObject.get(name);
                Object redisName = redisOldJson.get(name);
                if (ObjUtil.isNull(requestCode) || ObjUtil.isNull(redisName)) {
                    continue;
                }
                if (ObjUtil.equals(requestCode, redisName)) {
                    continue;
                }
                String value = annotation.value();

                Class<? extends BaseEnum> modelTypeEnumClass = annotation.modelTypeEnums();

                BaseEnum[] enumConstants = modelTypeEnumClass.getEnumConstants();
                //如果不为空, 需要映射 在进行 拼接
                //如果为空, 直接查找老数据进行拼接
                String oldValueDesc = "";
                if (ObjUtil.isNotNull(enumConstants)) {
                    for (BaseEnum enumConstant : enumConstants) {
                        if (enumConstant.getCode().equals(String.valueOf(redisName))) {
                            oldValueDesc = enumConstant.getDesc();
                            break;
                        }
                    }
                    for (BaseEnum enumConstant : enumConstants) {
                        if (enumConstant.getCode().equals(String.valueOf(requestCode))) {
                            System.err.println("字段:【" + value + "】，由:[" + oldValueDesc + "],修改为: [" + enumConstant.getDesc() + "]");
                            break;
                        }
                    }
                    continue;
                }
                System.err.println("字段:【" + value + "】，由:[" + redisName + "],修改为: [" + requestCode + "]");
                log.info("字段:{},备注信息:{},注解参数:{}", name, annotation.value(), annotation);
            }
        }
        if (MysqlModeEnums.UPDATE == opLog.mysqlMode()) {
            log.info("更新操作");
        }

       // LogEntity logEntity  = initLogEntityBuild();
        try {
            Object proceed = joinPoint.proceed();
        } catch (Throwable e) {
            throw new RuntimeException(e);
        } finally {

        }
    }

    /**
     * 保存日志信息
     *
     * @param op
     */
    public void saveLog(OpLog op) {

    }
}
